package cn.good.yan.service.t6;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 6. CAS
 * 自己写一个CAS ，原子类 - 存线程 （实现加锁、解锁）
 *
 * @author shengren.yan
 * @create 2024-03-30
 */
public class CASDemo3 {

    // 自己写一个CAS ，原子类 - 存线程 （实现加锁、解锁）
    AtomicReference<Thread> atomicReference = new AtomicReference<>();

    // 加锁方法
    public void lock() {
        Thread thread = Thread.currentThread();
        System.out.println(Thread.currentThread().getName() + "\t" + "----该线程-- 已进来");
        // 自旋锁
        while (!atomicReference.compareAndSet(null, thread)) {
            System.out.println(Thread.currentThread().getName() + "\t" + "----该线程- 没有抢到锁-- 正在自旋");
        }
    }

    // 解锁方法
    public void unLock() {
        Thread thread = Thread.currentThread();
        atomicReference.compareAndSet(thread, null);
        System.out.println(Thread.currentThread().getName() + "\t" + "----该线程-- 已解锁.");
    }

    // 该线程：正在处理任务
    public void doDeal() {
        System.out.println(Thread.currentThread().getName() + "\t" + "----该线程-- 正在处理.");
    }

    public static void main(String[] args) {
        CASDemo3 spinLockDemo = new CASDemo3();
        new Thread(() -> {
            // A 线程 加锁 ----
            spinLockDemo.lock();
            spinLockDemo.doDeal();
            // 暂停几秒钟线程
            try {
                TimeUnit.MILLISECONDS.sleep(25);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // A 线程 解锁 ----
            spinLockDemo.unLock();
        }, "A").start();

        // 暂停500毫秒,线程A先于B启动
        try {
            TimeUnit.MILLISECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            // B 线程 加锁 ----
            spinLockDemo.lock();
            spinLockDemo.doDeal();
            // B 线程 解锁 ----
            spinLockDemo.unLock();
        }, "B").start();
    }

}
